from config import *
from help import *
from gui_sub import *

class my77(QMainWindow):
    def __init__(self):
        super().__init__()                     
        self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint|Qt.ToolTip)                          
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setGeometry(0, 0, 0, 0)
        self.hide()            
        self.show()
        self.co = 0
        self.co2 = 0
        t = QTimer(self)
        t.timeout.connect(self.ont)
        t.start(round(100/6))
        self.last = None
        self.zl = []
        self.showl = set()
        self.show_one_time = 0
        self.one_pos = (0, 0)
        cfg.w2showing = False            
        self.cir = wcir(False, True)
        self.cirsign = (0, )
        self.lastxy = (0, 0)
        self.lastRefreshTime = 0
        self.lastRefreshTimeDu = 0
        cfg.w2_to_changing = False
        cfg.w2_last_ge = 0
        cfg.w2_last_to = 0
        cfg.w2_last_dis = 0            
        self.fix_c = wcir(False)
        self.sca_c = wcir(True)
        for i in range(max_zi):
            self.zl.append(wzi())

    def needRet(self):        
        if cfg.show_one_onetime:
            cfg.show_one_onetime = False
            return False
        
        if is_sca():
            return False
        
        if cal_mouse_d(cfg.fix_pos) == 0:
            return False        
        
        if  cfg.force_show:            
            return False
            
        if cfg.mouse_mode in (0, 1):
            if cfg.w2_to_changing:
                return False
            #print('ret true')
            return True
        
        if cfg.mouse_mode == 2:
            return False
        
        cfg.show_one_on = False
        print('mode', cfg.mouse_mode)
        return False        
        
    def draw_cir(self):
        x,y =  get_cur_pos()
        s = (cfg.isShow, cfg.show_one_on, cfg.w2showing, cfg.show_mouse_tip,cfg.show_mouse_tip2, x, y,
             cfg.force_show, cfg.show_one_onetime, cfg.mouse_mode, cfg.has_invert, cfg.has_pos_vert)
        
        if self.cirsign == s:
            return
        
        self.cirsign = s
        if cfg.mouse_mode < 0:
            self.cir.hide()
            
        elif cfg.isShow or (cfg.show_one_on and cfg.w2showing and cfg.show_mouse_tip and cfg.show_mouse_tip2):
            self.cir.draw(x+cir_para[0]+cir_para[4], y+cir_para[1]+cir_para[5])
            ff = (cfg.has_invert and not cfg.has_pos_vert) or  cfg.force_show
            if self.cir.f != ff:
                self.cir.f = ff
                self.cir.update()

        elif not cfg.isShow and cfg.show_one_on and not cfg.w2showing and cfg.show_mouse_tip and not cfg.show_one_onetime:
            if cfg.mouse_mode == 1:
                self.cir.draw(cfg.fix_pos[0], cfg.fix_pos[1])
                if not self.cir.f:
                    self.cir.f = True
                    self.cir.update()                
            else:
                self.cir.draw(x+cir_para[0], y+cir_para[1])
                if self.cir.f != cfg.force_show:
                    self.cir.f = cfg.force_show
                    self.cir.update()
        else:
            #print('mouse hide', cfg.show_one_on)
            self.cir.hide()

    def cal_to(self):
        if time.time()-cfg.to_change_time>to_lap:
            if cfg.w2_to_changing:
                cfg.w2_to_changing = False
                cfg.w2_last_to = cfg.to
                cfg.w2_last_ge = cfg.last_ge
                cfg.w2_last_dis = cal_dis(get_cur_pos(), cfg.fix_pos)
                cfg.w2_min_ge = self.cal_ge(cfg.to)
            return
        
        if not cfg.w2_to_changing:
            cfg.w2_to_changing = True
    def get_show_l(self):
        a = sorted(self.showl,key=lambda x: int(x[0]))
        sl = set()
        
        if len(a) == 0:
            return sl
        
        if int(a[0][0]) == 0:
            sl.add(a[0])
            a = a[1:]
        if len(a) < 2:
            return self.showl
        d = cal_dis((a[0][1],a[0][2]),(a[1][1],a[1][2]) )
        if d == 0:
            return self.showl
        ne = get_near_count(d)
        
        sl.update( a[0:ne])
        last_idx = 0
        for i in range(len(a)):
            if is_in_cur_screen(a[i][1], a[i][2]):
                last_idx = i
        
        sl.update(a[ max(0, last_idx+1-get_far_count(d)):last_idx+1])
        end1 = last_idx
        si, ei = add_idx(last_idx+1-get_far_count(d), ne-1, d)
        sl.update(a[si:ei])
        
        last_idx = 0
        for i in range(len(a)):
            if is_in_all_screen(a[i][1], a[i][2]):
                last_idx = i
        
        sl.update(a[ max(0, last_idx+1-get_far_count(d)):last_idx+1])
        si, ei = add_idx(last_idx+1-get_far_count(d), end1, d)
        sl.update(a[si: ei])
        return sl                
        
    def ont(self):
        if cfg.x2_mode:
            return
        check_mouse_mode()
        self.cal_to()
        self.draw_cir()        
        cur = (0, 0)
        if cfg.isShow or cfg.show_one_on:
            cur = get_cur_pos()
        
        sign =  (cfg.isShow, cfg.fix_pos, cur, cfg.sum,cfg.sca, cfg.sca_du, cfg.sca_cur, cfg.sca_cur_pos, 
                 cfg.show_one_on, cfg.to, cfg.showCut, cfg.fix_scroll)
        if self.last == sign and not cfg.show_one_onetime and time.time() - cfg.to_time > 0.5:
            return
        
        self.co2 += 1
        if  (cfg.fix_scroll == 0) and not cfg.isShow and cfg.show_one_on and not cfg.w2showing and self.needRet():
            return                    
            
        if self.co2 % 100 == 0:
            print('co2', self.co2)
        self.last = sign
        self.showl = []
        self.fix_c_show = False
        self.sca_c_show = False       
            
        self.paintEvent2(1)
        cfg.fix_scroll = 0
        
        if not self.fix_c_show:
            self.fix_c.hide()
        if not self.sca_c_show:
            self.sca_c.hide()

        cfg.w2showing = False
        cfg.w2snap =copy.deepcopy(self.showl)                
        sl = self.get_show_l()
        maxi = 0
        for i in self.showl:
            st, x, y = i
            idx = int(st)
            if i in sl and idx > maxi:
                maxi = idx
        
        cfg.maxi = maxi
        for i in range(max_zi):
            if i >= len(self.showl) or ( cfg.showCut and not cfg.isShow and self.showl[i] not in sl):
                self.zl[i].hide()
            else:
                zi, x, y = self.showl[i]
                cfg.w2showing = True                
                cfg.force_show = False
                if int(zi) == maxi:
                    self.zl[i].draw(zi, x, y, True)                    
                else:
                    self.zl[i].draw(zi, x, y, False)
                    
                if not cfg.isShow and cfg.show_one_on:
                    self.one_pos = (x, y)
        
        
    def get_xy(self):            
        if cfg.isShow or  time.time() - cfg.to_time > 0.3:
            x, y = getp(None, False)
            self.lastRefreshTime = time.time()            
            return x, y
        
        if  time.time() - self.lastRefreshTime < 0.4:
            x,y = getp(None, False)            
            x2, y2=  self.lastxy
            if time.time() - self.lastRefreshTimeDu<du_refresh_interval:
                return x2,y2
            
            self.lastRefreshTimeDu = time.time()
            d1 = cal_dis(cfg.fix_pos,(x,y))
            d2 = cal_dis(cfg.fix_pos,(x2,y2))
            if d2==0:
                return x2,y2
            
            du = math.atan2(y-cfg.fix_pos[1],x-cfg.fix_pos[0])
            return(cfg.fix_pos[0]+math.cos(du)*d2 ,cfg.fix_pos[1]+math.sin(du)*d2 )            
          
        x, y = getp(None, False)
        self.lastRefreshTime = time.time()
        return x, y                                


    def cal_ge(self, to):                          
        dx = min_d
        dy = 0
        ll = math.sqrt(dx*dx+dy*dy)
        
        step = max(1, math.ceil(min_d / ll))
        st = step
        min_idx = step
        for i in range(step,max_l, step):
            if i * ll > min_d_mouse:
                min_idx = i
                break              
        st = min_idx               
        rr =  range(st, max_l, step)
        l = []
        for i in rr:            
            zx = dx * i
            zy = dy * i
            l.append((str(i), zx, zy))            
            gg = 1
                
            if len(l) >= max_zi:
                break

            if len(l)>=gg and i*ll>to:
                break
                           
            if i * ll > max_l:
                break
        return len(l)
        
    
    def needBreak(self, i, ll, gg):
        if len(self.showl) < gg:
            return False
        
        if not is_sca():
            real_l = len(self.showl)
        else:
            real_l = len(self.showl) - 1
            
        if cfg.w2_last_dis > min_d:
            pos =  get_cur_pos()
            if is_sca():
                pos = cfg.sca_cur_pos
            if cal_dis(pos, cfg.fix_pos) > cfg.w2_last_dis:                
                if real_l >= cfg.w2_last_ge:
                    return True                                                    
            else:
                if i * ll >= cfg.w2_last_to:
                    return True
        else:
            pos =  get_cur_pos()
            if is_sca():
                pos = cfg.sca_cur_pos            
            if cal_dis(pos, cfg.fix_pos) < min_d:
                if i * ll >= cfg.w2_last_to:
                    return True
            else:
                if real_l >= cfg.w2_min_ge:
                    return True   
            
        return False
        
    def paintEvent2(self,e):        
        if not cfg.isShow and not cfg.show_one_on:
            return
        
        self.co += 1
        if self.co % 300 == 0:
            print('paintEvent1',self.co,time.monotonic())
            
        x, y = self.get_xy()
        self.lastxy = (x, y)
        sx, sy = cfg.fix_pos
        dx = x - sx 
        dy = y - sy
        ll = math.sqrt(dx*dx+dy*dy)
        
        if round(dx) == 0 and round(dy) == 0:
            return

        step = max(1, math.ceil(min_d / ll))
        st = step
        min_idx = step
        for i in range(step,max_l, step):
            if i * ll > min_d_mouse:
                min_idx = i
                break
            
        if not cfg.isShow:
            st = min_idx
       
        if is_sca():
            rr = [0] + list(range(st, max_l, step))
        else:
            rr =  range(st, max_l, step)

        max_ll = 0
        to_lock.acquire()

        for i in rr:            
            zx = round(dx * i + x)
            zy = round(dy * i + y)
            if i == min_idx and len(self.showl) > 0:
                a =  self.showl[0]
                self.showl.append(a)
                self.showl[0] =  (str(i), zx, zy)                
            else:
                self.showl.append((str(i), zx, zy))
            max_ll = max(max_ll,i)            
            gg = max_zi
            if not cfg.isShow:
                gg = 1
                if is_sca():
                    gg = 2
                
            if len(self.showl) >= max_zi:
                break

            if not cfg.isShow:
                if cfg.fix_scroll != 0:                    
                    if len(self.showl)>=gg and i >= (cfg.maxi + cfg.fix_scroll):
                        print('break', i)
                        break
                    
                elif cfg.w2_to_changing:
                    if len(self.showl)>=gg and i*ll>= cfg.to:
                        break                    
                else:
                    if self.needBreak(i, ll, gg):
                        break                    
            else:
                if len(self.showl)>=gg:
                    break

            if i * ll > max_l:
                break

        if not cfg.w2_to_changing or cfg.fix_scroll != 0:
            cfg.to = max_ll*ll
        if cfg.fix_scroll != 0:
            set_to_change_time()
            cfg.w2_to_changing = True
            
        to_lock.release()
        
        if not is_sca():
            cfg.last_ge = len(self.showl)
        else:
            cfg.last_ge = len(self.showl) -1                    

        if not is_sca():
            return
        
        self.sca_c_show = True
        self.fix_c_show = True
       
        self.fix_c.draw(sx, sy)
        self.sca_c.draw(cfg.sca_cur_pos[0], cfg.sca_cur_pos[1])
            